# -*- coding: utf-8 -*-
from copy import copy
def simple(n):
    """ Функция для нахождения простых чисел.
    Алгоритм заканчивает работу либо при нахождении делителя,
    либо если проверяемый делитель станет больше корня из n.
    Чиcло n является простым, если алгоритм закончился по причине
    того, что проверяемый делитель стал больше, чем корень из n.
    Функция возвращает True если число простое.
    """

    if n % 2 == 0:
        return n == 2
    d = 3
    while d * d <= n and n % d != 0:
        d += 2
    return d * d > n

class NOD(object):
    """
    Класс для нахождения наибольшего общего делителя для неограниченного количества введенных чисел
    """
    def __init__(self, *args):
        self.d = dict() # Словарь для хранения простых множителей
        self.args = list(args) # Получаем список чисел для поиска НОД
        self.factor() # Находим простые множители каждого числа
        self.find_max_elements() # Находим число с наибольшим количеством множителей

    def factor(self):
        """
        Метод расскладываем каждое число на простые множители
        """
        for n in self.args:
            self.d[n] = list()
            if simple(n):
                self.d[n].append(n)
            else:
                for m in range(n):
                    if simple(m) and m!=1:
                        k=n
                        while k%m==0:
                            self.d[n].append(m)
                            k=k//m
        print(self.d) # выводит для каждого числа его простые множители в формате словаря
        return self.d

    def find_max_elements(self):
        """
        Метод находит число с максимальным количеством множителей
        """
        max_element_len=0
        self.max_element_in=None
        for item in self.d:
            if len(self.d[item])>max_element_len:
                self.max_element_in=item

    def find(self, items=[]):
        if items:
            self.args=items
            #print(self.args)
            self.factor()
            self.find_max_elements()
        self.nod = 1
        dct_copy = copy(self.d)
        for item in self.d[self.max_element_in]:
            lst = list()
            for key in self.d:
                if key != self.max_element_in:
                    if item in dct_copy[key]:
                        dct_copy[key].remove(item)
                        if item not in lst:
                            lst.append(item)
                    elif item in lst:
                        lst.remove(item)
                        break
                    else:
                        break
            if len(lst)>0:
                for item in lst:
                    self.nod*=item
        return self.nod

class NOK(object):
    # Класс для нахождения Наименьшего общего кратного
    def __init__(self, *args):

        self.args = list(set(list(args)))
        pass

    def remove_doubles(self):

        pass

    def find(self, items=[]):
        if items:
            self.args=list(set(items))
        pr=1
        next=self.args[0]
        for i in range(1, len(self.args)):
            nod = NOD(next, self.args[i]).find()
            next = int(next*self.args[i]/nod)
        return next

if __name__ == '__main__':
    lst = [int(item) for item in input('Введите числа через запятую: ').replace(' ','').split(',')]
    print("Наибольший общий делитель ", lst, ": ", NOD().find(lst))
    print("Наименьшее общее кратное", lst,": ", NOK().find(lst))
